package com.github.cdisk.xtrans.core;

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

import com.github.cdisk.xtrans.exception.DuplicateVariableNameException;
import com.github.cdisk.xtrans.exception.NoVariableNameException;

/**
 * 读取和初始化全局变量配置文件
 * @author Cdisk
 *
 */
public class GlobalVariables {

	private static final Logger LOGGER = Logger.getLogger(GlobalVariables.class);

	private Map<String, String> variables = new HashMap<String, String>();

	public GlobalVariables(String file) throws Exception {
		File global = new File("config.xml"); // 全局配置文件
		if (global.exists()) {
			loadXml(global); // 如果存在全局配置，就加载全局配置
		}
		if (!StringUtils.isEmpty(file)) { // 加载指定文件
			loadXml(new File(file));
		}
	}

	public String get(String variable) {
		return variables.get(variable);
	}

	/**
	 * 把传入字符串中的变量都替换为变量的实际值
	 * @param value
	 * @throws NoVariableNameException 
	 * @throws Exception 
	 */
	public String replaceVariables(String value) throws NoVariableNameException {
		if (StringUtils.isEmpty(value)) return value; // 传入字符串是空的，返回原始值。
		if (!value.matches(".*\\$\\{global\\.(.*?)\\}.*")) return value; // 传入字符串不包含变量，返回原始值。
		Pattern pattern = Pattern.compile("\\$\\{global\\.(.*?)\\}");
		Matcher matcher = pattern.matcher(value);
		while (matcher.find()) {
			String key = matcher.group(0); // 替换字符串
			String var = matcher.group(1); // 变量名
			String varValue = variables.get(var);
			if (varValue == null) {
				throw new NoVariableNameException("没有找到这个全局变量：" + var);
			}
			value = value.replace(key, varValue);
			value = StringUtils.trimToNull(value);
		}
		return value;
	}

	/**
	 *  替换execute的传入参数变量
	 * @param value
	 * @throws NoVariableNameException 
	 * @throws Exception 
	 */
	public static String replaceInputVariables(String value, Map<String, Object> input) throws NoVariableNameException {
		if (StringUtils.isEmpty(value)) return value; // 传入字符串是空的，返回原始值。
		if (!value.matches(".*\\$\\{(.*?)\\}.*")) return value; // 传入字符串不包含变量，返回原始值。
		Pattern pattern = Pattern.compile("\\$\\{(.*?)\\}");
		Matcher matcher = pattern.matcher(value);
		while (matcher.find()) {
			String key = matcher.group(0); // 替换字符串
			String var = matcher.group(1); // 变量名
			Object varValue = getInputValue(var, input);
			if (varValue == null) {
				throw new NoVariableNameException("没有从上一步输入中获取到：" + var);
			}
			value = value.replace(key, String.valueOf(varValue));
		}
		return value;
	}

	/**
	 * 获取input中的参数，想解决多层参数获取的问题，但目前只实现了多层$parent的获取。
	 * @param key
	 * @param input
	 * @return
	 */
	public static Object getInputValue(String key, Map<String, Object> input) {
		Object result = null;
		if (key.startsWith("$parent.")) {
			Object parent = input.get("$parent");
			if (parent == null || !(parent instanceof Map<?, ?>)) {
				return null;
			}
			input = (Map<String, Object>) parent;
			result = getInputValue(key.replaceAll("^\\$parent\\.", "") ,input);
		} else {
			result = input.get(key);
		}
		return result;
	}

	public static void main(String[] args) throws Exception {
//		GlobalVariables variables = new GlobalVariables("D:\\ddj\\config.xml");
//		System.out.println(variables.replaceVariables("jdbc://${global.user_point}:${car_info}/dbname"));
//		System.out.println();
//		String value = "jdbc://${user_point}:${car_info}/dbname";
//		String regex = ".*\\$\\{(.*)?\\}.*";
//		System.out.println(value.matches(regex));
		
		
		System.out.println("$parent.$parent.a".replaceAll("^\\$parent\\.", ""));
	}

	private void loadXml(File file) throws ParserConfigurationException, SAXException, IOException, NoVariableNameException, DuplicateVariableNameException {
		LOGGER.info("正在加载变量配置：" + file.getAbsolutePath());
		DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
		DocumentBuilder builder = factory.newDocumentBuilder();
		Document doc = builder.parse(file);
		NodeList nodeList = doc.getElementsByTagName("variable");
		int length = nodeList.getLength();
		for (int i = 0; i < length; i++) {
			Element el = (Element) nodeList.item(i);
			String name = el.getAttribute("name");
			if (StringUtils.isEmpty(name)) {
				throw new NoVariableNameException("变量配置没有指定变量名称。");
			}
			if (variables.get(name) != null) {
				throw new DuplicateVariableNameException("名称已存在了：" + name);
			}
			String value = el.getTextContent().trim();
//			if (StringUtils.isEmpty(value)) {
//				throw new VariableBlankException("变量值是空的：" + name);
//			}
			variables.put(name, value);
		}
	}
}
